﻿using System;
using System.Collections.ObjectModel;
using YKXiangQi.Common;
using YKXiangQi.Enums;
using YKXiangQi.EventHandlers;
using YKXiangQi.Models;

namespace YKXiangQi.ViewModels
{
    public class EditBoardViewModel: DialogViewModel
    {
        private readonly string _fen;
        
        public RelayCommand SetStartPositionCommand { get; private set; }
        public RelayCommand SetCurrentPositionCommand { get; private set; }
        public RelayCommand SetEmptyPositionCommand { get; private set; }
        public RelayCommand OkCommand { get; private set; }
        public RelayCommand CancelCommand { get; private set; }

        public BoardViewModel Board { get; set; }

        private ObservableCollection<PieceViewModel> _pieces; 
        public ObservableCollection<PieceViewModel> Pieces
        {
            get { return _pieces; }
            private set
            {
                _pieces = value;
                RaisePropertyChanged(() => Pieces);
            }
        }

        public PieceViewModel SelectedPiece { get; set; }

        private bool _isRedFirst;
        public bool IsRedFirst
        {
            get { return _isRedFirst; }
            set
            {
                _isRedFirst = value;
                Board.Turn = _isRedFirst ? Sides.Red : Sides.Black;
                RaisePropertyChanged(() => IsRedFirst);
            }
        }

        public EditBoardViewModel(string fen)
        {
            _fen = fen;
            SetStartPositionCommand = new RelayCommand(SetStartPosition);
            SetCurrentPositionCommand = new RelayCommand(SetCurrentPosition);
            SetEmptyPositionCommand = new RelayCommand(SetEmptyPosition);
            OkCommand = new RelayCommand(OnOk);
            CancelCommand = new RelayCommand(OnCancel);

            Board = new BoardViewModel(BoardSize.Small, fen, BoardMode.Editing);
            Board.LeftMouseDown += BoardLeftMouseDown;
            Board.PieceLeftMouseDown += PieceOnBoardLeftMouseDown;
            InitPieces();
            IsRedFirst = true;
        }

        private void SetStartPosition(object param)
        {
            Board.SetBoard(Constant.DefaultFen);
        }

        private void SetCurrentPosition(object param)
        {
            Board.SetBoard(_fen);
        }

        private void SetEmptyPosition(object param)
        {
            Board.SetBoard(Constant.EmptyFen);
        }

        private void OnOk(object param)
        {
            OnRequestClose(true);
        }

        private void OnCancel(object param)
        {
            OnRequestClose(false);
        }

        private void InitPieces()
        {
            _pieces = new ObservableCollection<PieceViewModel>
                          {
                              new PieceViewModel(new Advisor() {Side = Sides.Red}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Advisor() {Side = Sides.Black}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Elephant() {Side = Sides.Red}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Elephant() {Side = Sides.Black}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Rook() {Side = Sides.Red}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Rook() {Side = Sides.Black}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Cannon() {Side = Sides.Red}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Cannon() {Side = Sides.Black}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Horse() {Side = Sides.Red}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Horse() {Side = Sides.Black}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Pawn() {Side = Sides.Red}) {BoardSize = BoardSize.Small},
                              new PieceViewModel(new Pawn() {Side = Sides.Black}) {BoardSize = BoardSize.Small}
                          };
            foreach (var piece in Pieces)
            {
                piece.LeftMouseDown += PieceLeftMouseDown;
                piece.RightMouseDown += PieceRightMouseDown;
            }
        }

        private void PieceLeftMouseDown(object sender, EventArgs e)
        {
            var piece = sender as PieceViewModel;
            if (piece == null) return;

            if (SelectedPiece != null)
            {
                SelectedPiece.State = PieceState.Normal;
            }

            SelectedPiece = piece;
            SelectedPiece.State = PieceState.Selected;
            Board.ClearSelectedPiece();
            
        }

        private void PieceRightMouseDown(object sender, EventArgs e)
        {
            if(SelectedPiece != null)
                SelectedPiece.State = PieceState.Normal;
            SelectedPiece = null;
        }

        private void BoardLeftMouseDown(object sender, BoardLeftMouseDownEventArgs e)
        {
            if(SelectedPiece != null)
            {
                var clonedPiece = SelectedPiece.Clone();
                clonedPiece.State = PieceState.Normal;
                Board.AddPiece(clonedPiece, e.Position);
                //SelectedPiece.State = PieceState.Normal;
                //SelectedPiece = null;
                e.Handled = true;
            }
        }

        private void PieceOnBoardLeftMouseDown(object sender, PieceLeftMouseDownEventArgs e)
        {
            if(SelectedPiece !=null)
                SelectedPiece.State = PieceState.Normal;
            SelectedPiece = null;
        }

        public string GetCurrentFen()
        {
            return Board.GetCurrentFen();
        }
    }
}
